#ifndef qbar
#define qbar

#include "interfaces.h"
#include "Color.h"
#include "QB.h"
#include "State.h"
#include "Transition.h"
#include "effects.h"
#include "Light.h"
#include "MotionSensor.h"
#include "Speaker.h"

/**
 * States
 */
 
class SleepState : public State
{
  public: 
    SleepState(QB* qb);
    State* execute();
    void enter();
    void exit();
  private:
    PulsateEffect _effect;
    long _startSleep;
};

class SoundState : public State 
{
  public:
    SoundState(QB* qb);
    State* execute();
    void enter();
  private:
    long _nextPlay;
	char _previousSide;
	int  _intensity;
};

class PlayState : public State 
{
  public:
    PlayState(QB* qb);
    State* execute();
    void enter();
  private:
    int  _agitation;
    long _startCrazy;
    long _lastReduction;
    long _lastLightChange;
    char _lastSide;
    int  _hue;
};

class ColorSmackState : public State
{
  public:
    ColorSmackState(QB* qb);
    State* execute();
    void enter();
  private:
    int  _hues[6];
    int  _currHue;
	int  _targetHue;
	int  _hue;
    long _lastChange;
};

class PuzzleState : public State
{
  public:
    PuzzleState(QB* qb);
    State* execute();
    void enter();
  private:
    int _c;
    long _lastChange;
};

class ScriptSelectState : public State
{
  public:
    ScriptSelectState(QB *qb, SoundState* senseState, ColorSmackState* createState, PuzzleState* puzzleState);
    State* execute();
    void enter();
  private:
    SoundState* _senseState;
    ColorSmackState* _createState;
    PuzzleState* _puzzleState;
};

class IdentifyState : public State
{
  public:
    IdentifyState(QB* qb);
    State* execute();
    void enter();
  private:
};

/**
 * Transitions
 */

class CalmTransition : public Transition
{
  public:
    CalmTransition(QB* qb, int timeout);
    boolean evaluate();
    void    init();
  private:
    QB* _qb;
    long _lastMove;
    int  _timeout;
};

class ClapTransition : public Transition
{
	public: 
		ClapTransition(int claps, QB* qb);
		boolean evaluate();
	private:
		QB*    _qb;
		int _claps;
};


class TimeTransition : public Transition
{
	public: 
		TimeTransition(long millis);
		boolean evaluate();
		void    init();
	private:
		long _time;
		long _start;
};

class MoveTransition : public Transition
{
	public: 
		MoveTransition(int treshold, QB* qb);
		boolean evaluate();
		void    init();
	private:
		long _treshold;
    QB* _qb;
};

class CountTransition : public Transition
{
	public: 
		CountTransition(int num, Countable* countable);
		boolean evaluate();
	private:
		Countable* _countable;
		int        _num;
};

class CommandTransition : public Transition
{
  public:
    CommandTransition(QB* qb, int command);
    boolean evaluate();
  private:
    QB* _qb;
		int _command;
};

#endif

